写给go开发者的gRPC教程

您所在的位置:网站首页 grpc context cancel 写给go开发者的gRPC教程

写给go开发者的gRPC教程

2024-07-16 06:05:54| 来源: 网络整理| 查看: 265

本篇为【写给go开发者的gRPC教程系列】第六篇

第一篇:protobuf基础

第二篇:通信模式

第三篇:拦截器

第四篇:错误处理

第五篇:metadata

第六篇:超时控制 👈

本系列将持续更新,欢迎关注👏获取实时通知

导言

一个合理的超时时间是非常必要的,它能提高用户体验,提高服务器的整体性能,是服务治理的常见手段之一

为什么要设置超时

用户体验:很多RPC都是由用户侧发起,如果请求不设置超时时间或者超时时间不合理,会导致用户一直处于白屏或者请求中的状态,影响用户的体验

资源利用:一个RPC会占用两端(服务端与客户端)端口、cpu、内存等一系列的资源,不合理的超时时间会导致RPC占用的资源迟迟不能被释放,因而影响服务器稳定性

综上,一个合理的超时时间是非常必要的。在一些要求更高的服务中,我们还需要针对DNS解析、连接建立,读、写等设置更精细的超时时间。除了设置静态的超时时间,根据当前系统状态、服务链路等设置自适应的动态超时时间也是服务治理中一个常见的方案。

客户端的超时 连接超时

还记得我们怎么在客户端创建连接的么?

conn, err := grpc.Dial("127.0.0.1:8009", grpc.WithInsecure(), ) if err != nil { panic(err) } // c := pb.NewOrderManagementClient(conn) // // Add Order // order := pb.Order{ // Id: "101", // Items: []string{"iPhone XS", "Mac Book Pro"}, // Destination: "San Jose, CA", // Price: 2300.00, // } // res, err := c.AddOrder(context.Background(), &order) // if err != nil { // panic(err) // }

如果目标地址127.0.0.1:8009无法建立连接,grpc.Dial()会返回错误么?这里直接放结论:不会的,grpc默认会异步创建连接,并不会阻塞在这里,如果连接没有创建成功会在下面的RPC调用中报错。

如果我们想控制连接创建时的超时时间该怎么做呢?

异步转成同步:首先我们需要使用grpc.WithBlock()这个选项让连接的创建变为阻塞式的 超时时间:使用grpc.DialContext()以及Go中context.Context来控制超时时间

于是实现如下,当然使用context.WithDeadline()效果也是一样的。连接如果在3s内没有创建成功,则会返回context.DeadlineExceeded错误

ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() conn, err := grpc.DialContext(ctx, "127.0.0.1:8009", grpc.WithInsecure(), grpc.WithBlock(), ) if err != nil { if err == context.DeadlineExceeded { panic(err) } panic(err) } 服务调用的超时

和上面连接超时的配置类似。无论是普通RPC还是流式RPC,服务调用的第一个参数均是context.Context

所以可以使用context.Context来控制服务调用的超时时间,然后使用status来判断是否是超时报错,关于status可以回顾之前讲过的错误处理

ctx, cancel = context.WithTimeout(context.Background(), 3*time.Second) defer cancel() // Add Order order := pb.Order{ Id: "101", Items: []string{"iPhone XS", "Mac Book Pro"}, Destination: "San Jose, CA", Price: 2300.00, } res, err := c.AddOrder(ctx, &order) if err != nil { st, ok := status.FromError(err) if ok && st.Code() == codes.DeadlineExceeded { panic(err) } panic(err) } 拦截器中的超时

普通RPC还是流式RPC拦截器函数签名第一个参数也是context.Context,我们也可以在拦截器中修改超时时间。错误处理也是和服务调用是一样的

需要注意的是context.WithTimeout(context.Background(), 100*time.Second)。因为Go中context.Context向下传导的效果,我们需要基于context.Background()创建新的context.Context,而不是基于入参的ctx,

func unaryClientInterceptor(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second) defer cancel() // Invoking the remote method err := invoker(ctx, method, req, reply, cc, opts...) if err != nil { st, ok := status.FromError(err) if ok && st.Code() == codes.DeadlineExceeded { panic(err) } panic(err) } return err } 服务端的超时 连接超时

服务端也可以控制连接创建的超时时间,如果没有在设定的时间内建立连接,服务端就会主动断连,避免浪费服务端的端口、内存等资源

s := grpc.NewServer( grpc.ConnectionTimeout(3*time.Second), ) 服务实现中的超时

服务实现函数的第一个参数也是context.Context,所以我们可以在一些耗时操作前对context.Context进行判断:如果已经超时了,就没必要继续往下执行了。此时客户端也会收到上文提到过的超时error。

func (s *server) AddOrder(ctx context.Context, orderReq *pb.Order) (*wrapperspb.StringValue, error) { log.Printf("Order Added. ID : %v", orderReq.Id) select { case


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭